<?php
/**
 *
 * useage in init function of module config controllerMap
 *
 * public function init()
{
//...
$this->controllerMap = array(
'category'=>array(
'class'=>'Admin.controllers.TermController',
'taxModule'=>'<module id>',
'voc'=>'<vocabulary alias|id>',
'actions'=>array(
'admin'=>'path.to.AdminAction',
'update'=>'path.to.UpdateAction',
...
)
),
);
//...
}
 *
 * view category "<module id>/category"
 *
 */
class TermController extends BackOfficeController
{
    public $defaultAction = 'admin';
    /**
     * @var string the default layout for the views. Defaults to '//layouts/column2', meaning
     * using two-column layout. See 'protected/views/layouts/column2.php'.
     */
    public $layout = '//layouts/column2';
    public $taxModule = 'system';
    public $voc = 0;
    //extend, add new or overide logic of Admin, create, update actions
    public $actions = array();

    private $_vocabulary;

    public function getVocabulary()
    {
        if ($this->_vocabulary === null) {
            if (is_numeric($this->voc))
                $this->_vocabulary = Vocabulary::model()->findByPk($this->voc);
            else
                $this->_vocabulary = Vocabulary::model()->findByAttributes(array('alias' => $this->voc));
        }
        return $this->_vocabulary;
    }


    /**
     * Renders a view.
     *
     * The named view refers to a PHP script (resolved via {@link getViewFile})
     * that is included by this method. If $data is an associative array,
     * it will be extracted as PHP variables and made available to the script.
     *
     * This method differs from {@link render()} in that it does not
     * apply a layout to the rendered result. It is thus mostly used
     * in rendering a partial view, or an AJAX response.
     *
     * @param string $view name of the view to be rendered. See {@link getViewFile} for details
     * about how the view script is resolved.
     * @param array $data data to be extracted into PHP variables and made available to the view script
     * @param boolean $return whether the rendering result should be returned instead of being displayed to end users
     * @param boolean $processOutput whether the rendering result should be postprocessed using {@link processOutput}.
     * @return string the rendering result. Null if the rendering result is not required.
     * @throws CException if the view does not exist
     * @see getViewFile
     * @see processOutput
     * @see render
     */
    public function renderPartial($view, $data = null, $return = false, $processOutput = false)
    {
        if (($viewFile = $this->getViewFile($view)) === false) {
            $view = 'Admin.views.term.' . $view;
        }
        return parent::renderPartial($view, $data, $return, $processOutput);
    }

    public function actions()
    {
        return CMap::mergeArray(array(
            'index' => array('class' => 'Admin.controllers.term.AdminAtion'),
            'admin' => array('class' => 'Admin.controllers.term.AdminAtion'),
            'create' => array('class' => 'Admin.controllers.term.UpdateAtion'),
            'update' => array('class' => 'Admin.controllers.term.UpdateAtion'),
        ), $this->actions);
    }

    /**
     * Deletes a particular model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id the ID of the model to be deleted
     */
    public function actionDelete()
    {
        if (($id = $this->get('id', null)) !== null) {
            $ids = is_numeric($id) ? array($id) : explode(',', $id);

            // delete one or multiple objects given the list of object IDs
            $result = FSM::run('Core.Term.delete', array('ids' => $ids));
            if ($result->hasErrors()) {
                echo $result->getError('ErrorCode');
            } elseif (!Yii::app()->request->isAjaxRequest) {
                // only redirect user to the admin page if it is not an AJAX request
                $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
            }
        } else {
            throw new CHttpException(400, Yii::t('Core', 'Cannot delete item with the given ID.'));
        }
    }

    public function actionUpdateOrder()
    {
        $ids = $this->get('items', array());
        if (count($ids)) {
            foreach ($ids as $id => $parentId) {
                $orders = array();
                if ($parentId == 'root') {
                    $orders = array_keys($ids, $parentId);
                    $parentId = 0;
                }
                else {
                    $parentId = (int)$parentId;
                    $orders = array_keys($ids, $parentId);
                }
                $order = 0;
                if (count($orders))
                    $order = (int)array_search($id, $orders);
                $order++;
                Term::model()->updateByPk($id, array('ordering' => $order));
                $model = TermHierarchy::model()->findByAttributes(array('term_id' => $id));
                if (is_object($model)) {
                    if ($parentId)
                        TermHierarchy::model()->updateAll(array('parent_id' => $parentId), 'term_id=:term_id', array(':term_id' => $id));
                    else
                        TermHierarchy::model()->deleteAllByAttributes(array('term_id' => $id));
                }
                elseif ($parentId) {
                    $model = new TermHierarchy;
                    $model->term_id = $id;
                    $model->parent_id = $parentId;
                    $model->save();
                }
            }
        }
    }

    public function actionStatus()
    {
        $termId = $this->get('id', 0);
        if ($termId) {
            $model = Term::model()->findByPk($termId);
            if (is_object($model)) {
                $model->state = $model->state == Term::STATE_ACTIVE ? Term::STATE_DEACTIVE : Term::STATE_ACTIVE;
                if (!$model->save(false, array('state'))) {
                    Yii::log(CVarDumper::dumpAsString($model->getErrors()), CLogger::LEVEL_ERROR);
                }
            }
        }
    }
}
